using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using QFramework;
using UnityEngine;
using WuLibrary;


namespace TowerDefence_QF
{
    public class LevelSystem : AbstractSystem
    {
       
        //存储敌人的集合
        private List<EnemyController> mEnemyList = new List<EnemyController>();
        /// <summary>
        /// 敌人系统
        /// </summary>
        private EnemySystem mEnemySystem;
        
        private PathSystem mPathSystem;
        /// <summary>
        /// 创建敌人的取消令牌
        /// </summary>
        private CancellationTokenSource mCeartEnemyCTS;
        /// <summary>
        /// 是否创建敌人
        /// </summary>
        private bool mIsCeartEnemy = false;
        /// <summary>
        /// 倒计时
        /// </summary>
        private int mCountDown = 5;
        /// <summary>
        /// 关卡路径
        /// </summary>
        private const string LEVEL_PATH = "Levels";
        /// <summary>
        /// 加载器
        /// </summary>
        private ResLoader mResLoader;
        /// <summary>
        /// 关卡
        /// </summary>
        private Levels mLevels;

        
        protected override void OnInit()
        {
            mEnemySystem = this.GetSystem<EnemySystem>();
            mPathSystem = this.GetSystem<PathSystem>();
            mResLoader=ResLoader.Allocate();
            LoadLevels();
            
            StringEventSystem.Global.Register(NameData.END_LEVEL, EndLevel);
        }

        protected override void OnDeinit()
        {
            StringEventSystem.Global.UnRegister(NameData.END_LEVEL,EndLevel);
            
            mResLoader.Recycle2Cache();
            mResLoader = null;
            mEnemyList.Clear();
            mEnemyList = null;
            mCeartEnemyCTS?.Cancel();
            mCeartEnemyCTS?.Dispose();
            mCeartEnemyCTS = null;
            mLevels = null;
            base.OnDeinit();
            
            
        }

        public void SetIsCreatEnemy(bool isCreat)
        {
            mIsCeartEnemy=isCreat;
        }
        
        private void LoadLevels()
        {
            mLevels = mResLoader.LoadSync<Levels>(LEVEL_PATH);
        }
        public void SetLevel(int levelIndex)
        {
            var level=mLevels.LevelList[levelIndex];
           
            mIsCeartEnemy = true;

            mCountDown = 5;
            
            mCeartEnemyCTS?.Cancel();
            mCeartEnemyCTS?.Dispose();
            mCeartEnemyCTS = null;
            mCeartEnemyCTS=new CancellationTokenSource(); 
            
            CeartEnemy(level).Forget();
        }

        private bool AreAnyEnemiesAlive()
        {
            return true;
        }

        private void EndLevel()
        {
            mIsCeartEnemy = false;
            
            mCeartEnemyCTS?.Cancel();
            
            RecyleEnemy();
        }

        public async UniTaskVoid CeartEnemy(Level level)
        {
           
            try
            {
                while (!mCeartEnemyCTS.IsCancellationRequested && mCountDown >= 0)
                {
                    await IsCreatEnemy();
                    Debug.Log($"倒计时:{mCountDown--}秒");
                    await UniTask.Delay(1000, cancellationToken: mCeartEnemyCTS.Token);
                }

                int waveCount = 0;
                foreach (var wave in level.Waves)
                {
                   
                   
                    var enemyGroup = wave.WaveEnemyGroup;
                    var enemyTypes = enemyGroup.WaveEnemyTypes;
                    
                    var timer = enemyGroup.SpawnInterval;
                    
                    if (waveCount != 0)
                    {
                        while (!mCeartEnemyCTS.IsCancellationRequested && timer >= 0)
                        {
                            await IsCreatEnemy();
                            timer--;
                            await UniTask.Delay(1000,cancellationToken: mCeartEnemyCTS.Token);
                        }
                    }
                    waveCount++;
                    
                    ColorDebugTools.Log($"{wave.WaveName}",LogColor.Red);
                    foreach (var enemyType in enemyTypes)
                    {
                        var count=enemyType.Count;
                        var spawnInterval = enemyType.SpawnInterval;
                        while (count > 0)
                        {
                            await IsCreatEnemy();
                            AllocateEnemy(enemyType.EnemyName);
                            count--;
                            await UniTask.Delay(TimeSpan.FromSeconds(spawnInterval),cancellationToken: mCeartEnemyCTS.Token);
                        }
                    }

                }

                mIsCeartEnemy = false;

            }
            catch (OperationCanceledException)
            {
                Debug.LogError("取消倒计时");
            }
            
        }
        private void AllocateEnemy(string name)
        {
            var enemy= mEnemySystem.Allocate(name);
            
            var MapPath = mPathSystem.GetV3List();

            var enemData = mEnemySystem.GetEnemyData(name);
            enemy.InitEnemy(MapPath,enemData,this);
          
            mEnemyList.Add(enemy);
            
            enemy.Show();
            ColorDebugTools.Log($"敌人：{name}",LogColor.Blue);
        }
        public void RecyleEnemy()
        {
            foreach (var enemy in mEnemyList)
            {
                mEnemySystem.Recycle(enemy);
            }
            mEnemyList.Clear();
        }

        public void RecyleEnemy(EnemyController enemyController)
        {
            if (mEnemyList.Contains(enemyController))
            {
                mEnemyList.Remove(enemyController);
            }
            mEnemySystem.Recycle(enemyController);
        }
       

        private async UniTask IsCreatEnemy()
        {
           
            if (!mIsCeartEnemy)
            {
                // 等待条件满足
                var isCanceled = await UniTask.WaitUntil(() => mIsCeartEnemy,cancellationToken:mCeartEnemyCTS.Token)
                    .SuppressCancellationThrow();
                if(isCanceled)
                    Debug.Log("取消创建敌人");
            }
        }
    }

}
